use serde_json::{Map, Value};
use std::fs::File;
use std::io::{self, Read, Write};

fn fetch_all_properties(ref_json: &Value, val: Value) -> Value {
    let mut has = false;
    if let Some(content_obj) = val.get("content") {
        let mut new_content_val = Map::new();
        for (_content_key, content_val) in content_obj.as_object().unwrap() {
            // let mut new_content_val = Map::new();
            if let Some(schema_obj) = content_val.get("schema") {
                if let Some(ref_obj) = schema_obj.get("$ref") {
                    let ref_value = ref_obj.as_str().unwrap();
                    // 使用 ref_value 从new_json_data 中找到对应的值
                    // println!("ref_value: {}", ref_value); // #/components/schemas/DomainBackupPoolQuery
                    let mut actual_value = ref_json.clone();
                    for key in ref_value.split("/").skip(1) {
                        // url decode 有中文  ex: %E9%92%89%E9%92%89%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%9E%E4%BD%93%E7%B1%BB
                        let new_key = match urlencoding::decode(key) {
                            Ok(v) => v.into_owned(),
                            Err(e) => {
                                println!("url decode error: {}", e);
                                key.to_string()
                            }
                        };
                        // println!("key: {}", new_key);
                        actual_value = actual_value.get(new_key).unwrap().clone();
                    }
                    // 取到->properties 取所有的属性，每个 properties 封装成一个对象 {}
                    if let Some(properties) = actual_value.get("properties") {
                        properties.as_object().unwrap().iter().for_each(|(k, v)| {
                            // let field_value = serde_json::json!({
                            //     k: v.clone(),
                            // });
                            has = true;
                            //v里面 去掉 required, example, description
                            if let Some(v_obj) = v.as_object() {
                                let mut new_v = Map::new();
                                v_obj.iter().for_each(|(k, v)| {
                                    if k == "required" || k == "example" || k == "description" {
                                        return;
                                    }
                                    new_v.insert(k.clone(), v.clone());
                                });
                                new_content_val.insert(k.clone(), Value::Object(new_v));
                            }
                            // new_content_val.insert(k.clone(), v.clone());
                        });
                    }
                }
            }
            // properties 这里是一个对象，需要封装成一个对象
            // let mut new_properties = Map::new();
            // new_properties.insert("properties".to_string(), Value::Object(new_content_val));
            // [{data:{}}]

            // new_content.insert(content_key.clone(), Value::Object(new_content_val));
            // new_content = new_content_val;
        }
        if has {
            //  Value::Object(new_content_val);
            // content -> application/json -> schema -> properties
            let mut properties = Map::new();
            properties.insert("properties".to_string(), Value::Object(new_content_val));
            let mut schema = Map::new();
            schema.insert("schema".to_string(), Value::Object(properties));
            let mut application_json = Map::new();
            application_json.insert("application/json".to_string(), Value::Object(schema));
            let mut content = Map::new();
            content.insert("content".to_string(), Value::Object(application_json));
            return Value::Object(content);
        }
    }
    val
}

pub fn process_apis() -> io::Result<()> {
    let base_path = "/Users/mojih/Documents/api-doc/api/723";
    let base_file_name = "Winstack930.openapi_v2.json";
    let path = format!("{}/{}", base_path, base_file_name);
    let new_path = format!("{}/new3_{}", base_path, base_file_name);

    let mut file = File::open(path)?;
    let mut data = String::new();
    file.read_to_string(&mut data)?;

    // 解析 JSON 数据
    let mut json_data: Value = serde_json::from_str(&data)?;
    let json_data_ref: Value = serde_json::from_str(&data)?;

    // 去掉 path->method->responses key 为非 200 的所有内容，只保留200的内容
    if let Some(data_obj) = json_data.get_mut("paths") {
        //遍历所有的 path
        //如果同一个path的method数大于1，把method 追加到path后，删除原来的path,创建新的path $path_$method
        let mut new_paths = Map::new();
        for (path, path_obj) in data_obj.as_object_mut().unwrap() {
            //遍历 path 下的所有 method
            for (method, method_obj) in path_obj.as_object_mut().unwrap() {
                if let Some(responses_obj) = method_obj.get_mut("responses") {
                    //只保留 200 的返回值 "200"其它值丢弃
                    let mut new_responses = Map::new();
                    for (status_code, response) in responses_obj.as_object().unwrap() {
                        if status_code == "200" {
                            let res = fetch_all_properties(&json_data_ref, response.clone());
                            new_responses.insert(status_code.clone(), res);

                            // new_responses.insert(status_code.clone(), response.clone());
                        }
                    }
                    *responses_obj = Value::Object(new_responses);
                }
                //去掉 summary, description, operationId 字段
                method_obj.as_object_mut().unwrap().remove("summary");
                method_obj.as_object_mut().unwrap().remove("description");
                method_obj.as_object_mut().unwrap().remove("operationId");
                method_obj.as_object_mut().unwrap().remove("deprecated");
                method_obj.as_object_mut().unwrap().remove("security");
                //去掉 parameters 中的 example, description 字段
                if let Some(parameters_obj) = method_obj.get_mut("parameters") {
                    for parameter in parameters_obj.as_array_mut().unwrap() {
                        parameter.as_object_mut().unwrap().remove("example");
                        parameter.as_object_mut().unwrap().remove("description");
                        // 去掉 required, example, description
                        parameter.as_object_mut().unwrap().remove("required");
                    }
                }
                //如果同一个path的method数大于1，把method 追加到path后，删除原来的path,创建新的path $path_$method
                let new_path = format!("{}_{}", method, path);
                // path_obj
                let mut new_path_obj = Map::new();
                new_path_obj.insert(method.clone(), method_obj.clone());
                new_paths.insert(new_path, Value::Object(new_path_obj));
            }
        }
        *data_obj = Value::Object(new_paths);
    }

    // 将修改后的 JSON 数据写入 new_compute.json 文件
    let mut new_file = File::create(new_path)?;
    let formatted_json = serde_json::to_string_pretty(&json_data).unwrap();

    new_file.write_all(formatted_json.to_string().as_bytes())?;

    Ok(())
}
